/**
 * Title: MyPriorityQueueBase1Test.java
 * Description: Tests the grow(int) method from MyPriorityQueue class using equivalence partitioning analysis
 * 			   for basis step 1 (Empty queue) 
 * Copyright: Copyright (c) 20defaultCapacity
 * Company: University of Texas at Arlington
 * @author: Duy Nguyen and Shreya Mamadapur
 * @version 1.0
 */

import java.util.Random;

import junit.framework.TestCase;
import junitx.util.PrivateAccessor;

import org.junit.Before;
import org.junit.Test;

public class MyPriorityQueueBase1Test extends TestCase {
	private static MyPriorityQueue mpq;	
	static Object[] o;
	static int exceptionThrown;
	int queueLength, capacity;
	int defaultCapacity = 0; 
	private Random random = null;

	@Before
	public void setUp() throws Exception {
		// obtain the default capacity by accessing the private variable called DEFAULT_INITIAL_CAPACITY 
		defaultCapacity = Integer.parseInt(PrivateAccessor.getField(
				MyPriorityQueue.class, "DEFAULT_INITIAL_CAPACITY").toString());
		random = new Random();
	}

	/**
	 * Test 1 - On an empty queue, 
	 * 			test the grow method by passing in a negative desired capacity, an exception should be thrown
	 * 
	 */
	@Test
	public void testGrowWithNegativeMinCapacity() {
		boolean exceptionThrown = false;

		mpq = new MyPriorityQueue();

		try {
			
			// invoke the private method by using private accessor 
			PrivateAccessor.invoke(mpq, "grow", new Class[] { int.class },
					new Object[] { new Integer(-10) });
		} catch (Exception e) {
			exceptionThrown = true;
		} catch (Throwable e) {
			exceptionThrown = true;
		}

		assertTrue(exceptionThrown);
	}

	/**
	 * Test 2 - On an empty queue, 
	 * 			test the grow method by passing in a 0 desired capacity,
	 * 			the new capacity should still be the default value
	 * 
	 */
	@Test
	public void testGrowWithZeroMinCapacityAndDefaultInitCap() {

		mpq = new MyPriorityQueue();

		try {
			PrivateAccessor.invoke(mpq, "grow", new Class[] { int.class },
					new Object[] { 0 });
			o = (Object[]) PrivateAccessor.getField(mpq, "queue");
			capacity = o.length;
			assertEquals(defaultCapacity, capacity);
		} catch (NoSuchFieldException e1) {
		} catch (Throwable e) {
		}

	}

	/**
	 * Test 3 - On an empty queue, 
	 * 			test the grow method by passing in a positive desired capacity,
	 * 			the new capacity should still be the default value (since 10 here is less than the default cap)
	 * 
	 */
	@Test
	public void testGrowWithPositiveMinCapacityAndDefaultInitCap() {

		mpq = new MyPriorityQueue();

		try {
			PrivateAccessor.invoke(mpq, "grow", new Class[] { int.class },
					new Object[] { 10 });
			o = (Object[]) PrivateAccessor.getField(mpq, "queue");
			capacity = o.length;

			assertEquals(defaultCapacity, capacity);

		} catch (NoSuchFieldException e1) {
		} catch (Throwable e) {
		}
	}

	/**
	 * Test 4 - On an empty queue, 
	 * 			test the grow method testing to see if the new capacity 
	 * 			is the same as the initial capacity
	 * 
	 */
	@Test
	public void testGrowWithPositiveMinCapacityAndInitCapGreaterThan64() {
		int inputCap = 64 + random.nextInt(100);
		mpq = new MyPriorityQueue(inputCap);

		try {
			o = (Object[]) PrivateAccessor.getField(mpq, "queue");
			capacity = o.length;
			assertEquals(inputCap, capacity);
		} catch (NoSuchFieldException e1) {
		} catch (Throwable e) {
		}

	}

	/**
	 * Test 5 - On an empty queue, 
	 * 			test the grow method testing to see if the new capacity 
	 * 			is the same as the min capacity when the desired capacity is less than the initial capacity
	 * 
	 */
	@Test
	public void testGrowForNewCapBeingSetToMinCap() {

		mpq = new MyPriorityQueue(64);
		int inputCapacity = 64 + random.nextInt(2000);
		try {

			PrivateAccessor.invoke(mpq, "grow", new Class[] { int.class },
					new Object[] { new Integer(inputCapacity) });

			o = (Object[]) PrivateAccessor.getField(mpq, "queue");
			capacity = o.length;
			assertEquals(inputCapacity, capacity);
		} catch (NoSuchFieldException e1) {
		} catch (Throwable e) {
		}

	}

}